﻿using Microsoft.Extensions.Options;
using mozhi.smarterp.AuthorCenter.Permissions.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
using Volo.Abp.SimpleStateChecking;

namespace mozhi.smarterp.AuthorCenter.Permissions
{
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(PermissionManager))]
    public class CustomPermissionManager : PermissionManager
    {
        private IPermissionGroupRepository _permissionGroupRepository;

        public CustomPermissionManager(IPermissionDefinitionManager permissionDefinitionManager, ISimpleStateCheckerManager<PermissionDefinition> simpleStateCheckerManager, IPermissionGrantRepository permissionGrantRepository, IServiceProvider serviceProvider, IGuidGenerator guidGenerator,
            IOptions<PermissionManagementOptions> options, ICurrentTenant currentTenant, IDistributedCache<PermissionGrantCacheItem> cache , IPermissionGroupRepository permissionGroupRepository) :
            base(permissionDefinitionManager, simpleStateCheckerManager, permissionGrantRepository, serviceProvider, guidGenerator, options, currentTenant, cache)
        {
            _permissionGroupRepository = permissionGroupRepository;
        }

        public override async Task SetAsync(string permissionName, string providerName, string providerKey, bool isGranted)
        {
            PermissionItem permission = await _permissionGroupRepository.GetItemAsync(permissionName);

            if(permission==null)
                throw new ApplicationException("The permission named '" + permissionName + "' is not exits!");

            await (ManagementProviders.FirstOrDefault((IPermissionManagementProvider m) => m.Name == providerName) ?? throw new AbpException("Unknown permission management provider: " + providerName)).
                SetAsync(permissionName, providerKey, isGranted).ConfigureAwait(continueOnCapturedContext: false);
        }

        public override async Task<List<PermissionWithGrantedProviders>> GetAllAsync(string providerName, string providerKey)
        {
            var permissionGrants = await PermissionGrantRepository.GetListAsync(providerName, providerKey);

            var result = new List<PermissionWithGrantedProviders>();

            foreach (var permissionGrant in permissionGrants)
            {
                result.Add(new PermissionWithGrantedProviders(permissionGrant.Name, true));
            }

            return result;
        }
    }
}
